//
//  PWBoundary.swift
//  EasyCoding
//
//  Created by JY_NEW on 2020/6/4.
//

import Foundation

///限制在最大最小值中间
@propertyWrapper
public struct PWBoundary<Value: Comparable> {
    public var value: Value
    public var min: Value?
    public var max: Value?
    
    public init(wrappedValue: Value, min: Value?, max: Value?) {
        value = wrappedValue
        self.min = min
        self.max = max
        assert(value >= (min ?? value) && value <= (max ?? value))
    }
    public init(wrappedValue: Value, _ range: Range<Value>) where Value: Strideable, Value.Stride: ExpressibleByIntegerLiteral {
        self.init(wrappedValue: wrappedValue, min: range.lowerBound, max: range.upperBound.advanced(by: -1))
    }
    public init(wrappedValue: Value, _ range: ClosedRange<Value>) {
        self.init(wrappedValue: wrappedValue, min: range.lowerBound, max: range.upperBound)
    }
    public init(wrappedValue: Value, _ range: PartialRangeFrom<Value>) {
        self.init(wrappedValue: wrappedValue, min: range.lowerBound, max: nil)
    }
    public init(wrappedValue: Value, _ range: PartialRangeUpTo<Value>) where Value: Strideable, Value.Stride: ExpressibleByIntegerLiteral {
        self.init(wrappedValue: wrappedValue, min: nil, max: range.upperBound.advanced(by: -1))
    }
    public init(wrappedValue: Value, _ range: PartialRangeThrough<Value>) {
        self.init(wrappedValue: wrappedValue, min: nil, max: range.upperBound)
    }
    
    public var wrappedValue: Value {
        get { return value }
        set {
            if let min, newValue < min {
                value = min
            } else if let max, newValue > max {
                value = max
            } else {
                value = newValue
            }
        }
    }
    /// 提供外部访问
    public var projectedValue: Self {
        return self
    }
}
